package com.we823.cms.controller.manage;

import java.io.Serializable;

import javax.servlet.http.HttpServletRequest;

import com.github.pagehelper.PageInfo;
import com.we823.cms.common.web.pageable.Direction;
import com.we823.cms.common.web.pageable.PageRequest;
import com.we823.cms.common.web.pageable.Sort;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.we823.cms.common.json.model.JqgridModel;
import com.we823.cms.common.utils.RequestUtil;
import com.we823.cms.core.security.shiro.PermissionStatus;
import com.we823.cms.model.BaseModel;
import com.we823.cms.repository.service.BaseService;

public abstract class AbstractManageController<T extends BaseModel<ID>,ID extends Serializable> extends SecurityBaseController implements BaseController<T, ID> {
	
	protected String baseUrl = "";
	
	protected String listUrl = "redirect:list.jspx";
	
	private BaseService<T, ID> baseService ;
	protected String entityName = "entity";
	
	public AbstractManageController(BaseService<T, ID> baseService) {
		this.baseService = baseService;
		setIndetity();
	}
	
	@RequestMapping("add")
	public String add(T entity, org.springframework.validation.BindingResult result) {
		check(PermissionStatus.CREATE);
		baseService.add(entity);

		return listUrl;
	}
	
	@Override
	@RequestMapping("delete")
	public String delete(@RequestParam(required=true,value="id",defaultValue="-1") ID key) {
		check(PermissionStatus.DELETE);
		baseService.delete(key);
		return listUrl;
	}
	
	@RequestMapping("edit")
	public String edit(T entity, BindingResult bindingResult) {
		check(PermissionStatus.UPDATE);
		baseService.edit(entity, null);
		return listUrl;
	}
	
	@RequestMapping("preEdit")
	public String preEdit(@RequestParam(required=true,value="id",defaultValue="-1")ID key, Model model) {
		check(PermissionStatus.VIEW);
		T t = baseService.findOne(key);
		model.addAttribute(entityName, t);
		return baseUrl + "preEdit";
	}
	
	@Override
	@RequestMapping("preAdd")
	public String preAdd(Model model) {
		check(PermissionStatus.CREATE);
		return baseUrl + "preAdd";
	}
	
	@Override
	@RequestMapping("list")
	public String list() {
		check(PermissionStatus.VIEW);
		return baseUrl + "list";
	}
	@Override
	@RequestMapping("getJson")
	@ResponseBody
	public Model getJson(HttpServletRequest request, Model model) {
		check(PermissionStatus.VIEW);
		boolean pageable = RequestUtil.getPageable(request);
		
		JqgridModel<T> jqgridModel = new JqgridModel<>(request, model);
		PageRequest pageRequest = getPageRequest(jqgridModel, request);
		PageInfo<T> pageData = getData(pageRequest, request, model,pageable);
		if(pageData!=null){
			jqgridModel.setDatarows(pageData.getList());
			jqgridModel.setRecords(pageData.getPages());
		}
		jqgridModel.flush();
		return model;
	}

	protected PageRequest getPageRequest(JqgridModel<T> jqgridModel,HttpServletRequest request){
		PageRequest pageRequest;
		int page = jqgridModel.getPage()-1;
		int size = jqgridModel.getRows();
		Sort sort = getSort(request);
		if(sort!=null){
			pageRequest = new PageRequest(page, size, sort);
		}else{
			pageRequest = new PageRequest(page, size);
		}
		return pageRequest;
	}
	
	/**
	 * 默认排序方式为jqgrid的指定的排序方式，若不使用默认排序，则覆写此方法
	 * @param request http的请求
	 * @return sort对象
	 */
	public Sort getSort(HttpServletRequest request){
		String sortString = RequestUtil.getValueByName(request, "sidx","");
		String sortType = RequestUtil.getValueByName(request, "sord", "asc");
		if(!"".equals(sortString)){
			Direction direction = Direction.parse(sortType);
			return new Sort(direction, sortString);
		}else{
			return null;
		}
	}
	/**
	 * 根据具体业务，填充数据模型。
	 * 数据表格显示时填充数据
	 * @param pageRequest 分页信息
	 * @param request 获取条件
	 * @param model 模型类
	 * @param pageable 是否需要分页
	 * @return pageInfo
	 */
	public abstract PageInfo<T> getData(PageRequest pageRequest,HttpServletRequest request,Model model,boolean pageable);
}
